﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using VH.SharePoint.Api.Entensions;
using VH.SharePoint.Api.Exceptions;
using VH.SharePoint.Api.Helpers;

namespace VH.SharePoint.Api
{
    public class BlogWeb : IDisposable
    {
        #region Fields
        private SPWebCollection _subwebs;
        #endregion

        #region Properties
        public SPWeb Web { get; private set; }
        public Guid Id {
            get { return Web.ID; }
        }
        public String Name {
            get { return Web.Title; }
            set { Web.Title = value; }
        }
        public String Description {
            get { return Web.Description; }
            set { Web.Description = value; }
        }
        public DateTime Created {
            get { return Web.Created; }
        }
        public SPUser CreatedBy {
            get { return Web.Author; }
        }
        public String Url
        {
            get { return Web.Url; }
        }
        public String ApiUrl
        {
            get { return Web.Url + SPConstants.EndPointApi; }
        }
        public Boolean IsAdmin {
            get { return Web.UserIsSiteAdmin; }
        }
        public Boolean IsRoot {
            get { return Web.ParentWebId == Guid.Empty || Web.ParentWebId == Web.ID; }
        }

        public Boolean IsEnabled {
            get { return this.Web.GetProperty<bool?>(SPConstants.BlogApiEnabled, false).Value; }
        }

        public Guid MediaLibraryId {
            get { return Web.GetProperty<Guid>(SPConstants.BlogMediaLibPB); }
            internal set { Web.SetProperty<Guid>(SPConstants.BlogMediaLibPB, value); }
        }
        public Guid PostLibraryId
        {
            get { return Web.GetProperty<Guid>(SPConstants.BlogPostLibPB); }
            internal set { Web.SetProperty<Guid>(SPConstants.BlogPostLibPB, value); }
        }
        public String MediaFolderName
        {
            get { return Web.GetProperty<String>(SPConstants.BlogMediaFolderPB,"blog"); }
            internal set { Web.SetProperty<String>(SPConstants.BlogMediaFolderPB, value); }
        }
        public Boolean IsPublishing
        {
            get { return PublishingWeb.IsPublishingWeb(Web); }
        }
        public Boolean ScriptTagsEnabled
        {
            get { return Web.GetProperty<Boolean>(SPConstants.BlogScriptTagsEnabled, false); }
            internal set { Web.SetProperty<Boolean>(SPConstants.BlogScriptTagsEnabled, value); }
        }
        #endregion

        #region Constructor
        private BlogWeb(SPWeb web)
        {
            Web = web;
        }

        
        #endregion

        #region Static
        public static BlogWeb GetBlogWeb(SPWeb web)
        {
            return new BlogWeb(web);
        }
        #endregion

        #region Methods
        private void EnsureEnabled()
        {
            if (!this.IsEnabled)
            {
                throw new ConfigurationErrorException("Blog API is not enabled for this SharePoint web site!");
            }
        }

        public void EnsureMediaLibrary()
        {
            EnsureEnabled();
            if (MediaLibraryId == default(Guid) || MediaLibraryId == Guid.Empty)
            {
                //Define default settings in publishing mode
                if (IsPublishing)
                {
                    var pubWeb = PublishingWeb.GetPublishingWeb(Web);
                    MediaLibraryId = pubWeb.ImagesLibrary.ID;
                    this.Update();
                }
                else
                    throw new NotSupportedException("The media library is not definied.");
            }
                
        }

        public void EnsurePostLibrary()
        {
            EnsureEnabled();
            if (PostLibraryId == default(Guid) || PostLibraryId == Guid.Empty)
            {
                //Define default settings in publishing mode
                if (IsPublishing)
                {
                    var pubWeb = PublishingWeb.GetPublishingWeb(Web);
                    PostLibraryId = pubWeb.PagesListId;
                    this.Update();
                }
                else
                    throw new NotSupportedException("The post library is not definied.");
            }
        }
        
        public IEnumerable<BlogWeb> GetBlogWebs()
        {
            _subwebs = _subwebs ?? Web.GetSubwebsForCurrentUser();
            return _subwebs.Select(w => new BlogWeb(w));
        }

        public MediaItemCollection GetMedias()
        {
            EnsureMediaLibrary();
            var res = new MediaItemCollection(this, this.MediaLibraryId);
            return res;
        }

        public PostItemCollection GetPosts()
        {
            EnsurePostLibrary();
            var res = new PostItemCollection(this, this.PostLibraryId);
            return res;
        }

        internal PageLayout GetDefaultLayout()
        {
            if (!IsPublishing) return null;
            var w = PublishingWeb.GetPublishingWeb(Web);
            return w.DefaultPageLayout;
        }

        public void EnableBlogApi()
        {
            EnableBlogApi(true);
        }

        public void DisableBlogApi()
        {
            EnableBlogApi(false);
        }

        private void EnableBlogApi(bool enable)
        {
            this.Web.SetProperty<bool>(SPConstants.BlogApiEnabled, enable);
            this.Update();
        }

        public void Update()
        {
            using (new SPUnsafeUpdate(Web))
            {
                Web.Update();
            }
        }

        public void Dispose()
        {
            if (Web != null && SPContext.Current.Web.ID != Web.ID)
            {
                Web.Dispose();
            }
            if (_subwebs != null)
            {
                foreach (SPWeb subweb in _subwebs)
                {
                    if(subweb!=null)
                        subweb.Dispose();
                }
            }
        }
        #endregion
    }
}
